// 节流
function throttled(fn, delay) {
    let startTime = Date.now();
    let timeout = null;
    return function() {
        let curTime = Date.now();
        let remaining = delay - (curTime - startTime);
        let context = this;
        let args = arguments;
        clearTimeout(timeout);
        if (remaining <= 0) {
            fn.apply(context, args);
            startTime = Date.now();
        } else {
            timeout = setTimeout(fn, remaining);
        }
    }
}

function throttled(fn, delay) {
    let startTime = Date.now();
    let timeout = null;
    return function() {
        let curTime = Date.now();
        let remain = delay - (curTime - startTime);
        let context = this;
        let args = arguments;
        clearTimeout(timeout);
        if (remain <= 0) {
            fn.apply(context, args);
            startTime = Date.now();
        } else {
            timeout = setTimeout(fn, remain);
        }
    }
}

// 防抖
function debounce(fn, wait) {
    let timeout = null;
    return function() {
        let context = this;
        let args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(context, args);
        }, wait);
    }
}

function debounce(fn, wait) {
    let timeout = null;
    return function() {
        let context = this;
        let args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(context, args);
        }, wait);
    }
}

// 深克隆
function deepClone(obj) {
    if (typeof obj === 'number' || typeof obj === 'String' || typeof obj === 'boolean' || typeof obj === 'undefined') {
        return obj;
    } else if (obj === null)
        return obj;
    else {
        let newObj = obj instanceof Array ? []  : {};
        for (let prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                newObj[prop] = deepClone(obj[prop]);
            }
        }
        return newObj;
    }
}
function deepClone(obj) {
    if (typeof obj === "number")
        return obj;
    else {
        let newObj = obj instanceof Array ? [] : {};
        for (let prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                newObj[prop] = deepClone(obj[prop]);
            }
        }
    }
    return newObj;
}

function deepClone(obj) {
    if (typeof obj === 'number' || typeof obj === 'string' || typeof obj === 'boolean' || typeof obj === 'undefined') {
        return obj; 
    } else if (obj === null) {
        return obj;
    } else {
        let newObj = obj instanceof Array ? [] : {};
        for (let prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                newObj[prop] = deepClone(obj[prop]);
            }
        }
        return newObj;
    }
}

// instanceOf
function myInstanceOf(left, right) {
    let rightProto = right.prototype;
    let leftProto = left.__proto__;
    while (true) {
        if (leftProto === null)
            return false;
        else if (leftProto === rightProto)
            return true;
        leftProto = leftProto.__proto__;
    }
}

// 手写new
function myNew(Func, ...args) {
    const obj = {};
    obj.__proto__ = Func.prototype;
    let result = Func.apply(obj, args);
    return result instanceof Object ? result : obj;
}

// call
Function.prototype.myCall = function(context) {
    context.fn = this;
    let args = [...arguments];
    context.fn(...args);
    let result = context.fn(...args);
    delete context.fn;
    return result;
}

// bind
Function.prototype.myBind = function (context) {
    if (typeof this !== "function")
        return new TypeError('Error');
    
    const args = [...arguments].slice(0), fn = this;
    console.log("arguments", arguments);
    console.log("args：",args);

    return function Fn() {
        return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
    }
}

function hello(a) {
    console.log(a);
}
let hello1 = hello.myBind()

console.log(new hello1(2));


var s1 = "get-element-by-id"

// 转化为 getElementById
var f = function (s) {
    return s.replace(/-\w/g, function (x) {
        console.log(x);
        return x.slice(1).toUpperCase();
    })
}
console.log(f(s1))
